using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Drawing;
using DevExpress.XtraEditors.Popup;
using DevExpress.XtraEditors.Registrator;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraEditors.ViewInfo;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Base;
using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace Comteck.Winforms.Controls {
  /// <summary>
  /// 自定义的GridLookupEdit,允许进行多列的匹配
  /// <para>参照：https://www.devexpress.com/Support/Center/Example/Details/E1985 </para>
  /// </summary>
  [ToolboxItem(true)]
  public class MyGridLookUpEdit : GridLookUpEdit {
    //private DevExpress.XtraGrid.Views.Grid.GridView fPropertiesView;

    /// <summary>
    /// 自动注册下拉框编辑器
    /// </summary>
    static MyGridLookUpEdit() {
      RepositoryItemMyGridLookUpEdit.RegisterCustomGridLookUpEdit();
    }

    /// <summary>
    /// 创建自定义GridLookupEdit
    /// </summary>
    public MyGridLookUpEdit() : base() {
      Initialize();
    }

    /// <summary>
    /// 初始化
    /// </summary>
    private void Initialize() {
      this.Tag = false;   // 设置全选标记
      this.Properties.AllowMouseWheel = false;
      //this.EnterMoveNextControl = true;
      this.Properties.ImmediatePopup = true;
      this.Properties.TextEditStyle = TextEditStyles.Standard;

      #region 编辑框默认自动全选 add by geping@2017-07-13

      // 鼠标移入文本编辑框触发事件
      this.Enter += (sender, e) => {
        // 设置全选标记
        this.Tag = true;
        this.SelectAll();
      };
      // 获取输入焦点时自动全选
      this.MouseUp += (sender, e) => {
        // 如果鼠标左键操作并且标记存在，则执行全选
        if (e.Button == MouseButtons.Left && (bool)this.Tag) {
          this.SelectAll();
        }

        // 取消全选标记
        this.Tag = false;
      };
      // 双击输入框时自动全选
      this.DoubleClick += (sender, e) => {
        this.SelectAll();
      };

      #endregion

      this.KeyDown += this.MyGridLookUpEdit_KeyDown;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void MyGridLookUpEdit_KeyDown(object sender, KeyEventArgs e) {
      if (e.KeyCode == Keys.Delete) {
        var control = sender as BaseEdit;
        if (control.ReadOnly) { return; }
        control.EditValue = null;
        e.Handled = true;
      } else if (e.KeyCode == Keys.Down) {
        e.Handled = true;

        this.ShowPopup();
        this.Properties.View.MoveFirst();

        //// 默认选中第一项
        //if (this.EditValue == null && this.Properties.PopupView.RowCount > 0) {
        //  this.Properties.PopupView.FocusedRowHandle = 0;
        //}

      } else if (e.KeyCode == Keys.Back) {
        if (this.IsPopupOpen == false) {
          e.Handled = true;

          this.ShowPopup();
          this.Properties.View.MoveFirst();
        }
      } else if (e.KeyData == (Keys.Control | Keys.V)) {
        // 支持ctrl + v 功能
        e.Handled = true;
        this.BeginInvoke(new Action(() => {
          this.AutoSearchText = this.Text;
          this.ShowPopup();
        }));
      }
    }

    /// <summary>
    /// 自定义编辑器名称
    /// </summary>
    public override string EditorTypeName => RepositoryItemMyGridLookUpEdit.MyGridLookUpEditName;

    /// <summary>
    /// 重写下拉框编辑器
    /// </summary>
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public new RepositoryItemMyGridLookUpEdit Properties => base.Properties as RepositoryItemMyGridLookUpEdit;

    //
    // 摘要:
    //     Gets or sets whether focus is moved to the next control (according to the tab
    //     order) when an end-user presses ENTER.
    [DefaultValue(true)]
    //[DevExpressXtraEditorsLocalizedDescriptionAttribute("BaseEditEnterMoveNextControl")]
    [DXCategory("Behavior")]
    public override bool EnterMoveNextControl { get; set; } = true;

    /// <summary>
    /// 
    /// </summary>
    /// <returns></returns>
    protected override PopupBaseForm CreatePopupForm() {
      return new MyGridLookUpPopupForm(this);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="e"></param>
    /// <returns></returns>
    public override bool IsNeededKey(KeyEventArgs e) {
      return this.Properties.IsNeededKey(e.KeyData);
    }

    /// <summary>
    /// 正常情况下，在输入第一个字符（主要是数字及字母）后，虽然自动弹出了下拉框并过滤了数据，
    /// 但是此时光标并未定位到下拉框中，导致回车后并未返回匹配到的首行记录
    /// 此处就是为了解决以上问题，展开下拉框时自动定位到首行
    /// add by geping@2019-02-18
    /// </summary>
    protected override void OnPopupShown() {
      base.OnPopupShown();

      BeginInvoke(new Action(() => {
        if (this.GetSelectedDataRow() == null) {
          this.Properties.View.FocusedRowHandle = 0;
        }
      }));
    }
  }

  /// <summary>
  /// 匹配自定义编辑器的下拉GridLookUpEdit
  /// </summary>
  [DXCategory("Properties")]
  [UserRepositoryItem("RegisterMyGridLookUpEdit")]
  public class RepositoryItemMyGridLookUpEdit : RepositoryItemGridLookUpEdit {
    /// <summary>
    /// 编辑器的名称
    /// </summary>
    public const string MyGridLookUpEditName = "MyGridLookUpEdit";
    
    /// <summary>
    /// 注册编辑器
    /// </summary>
    static RepositoryItemMyGridLookUpEdit() {
      RegisterCustomGridLookUpEdit();
     
    }

    /// <summary>
    /// 创建自定义的编辑器
    /// </summary>
    public RepositoryItemMyGridLookUpEdit() {
      // 默认允许过滤
      //this.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.Standard;
      // 不允许自动完成
      base.AutoComplete = false;

      this.KeyDown += this.RepositoryItemMyGridLookUpEdit_KeyDown;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void RepositoryItemMyGridLookUpEdit_KeyDown(object sender, KeyEventArgs e) {
      if (e.KeyData == (Keys.Control | Keys.V)) {
        // 支持ctrl + v 功能
        e.Handled = true;

        var column = sender as GridLookUpEdit;
        if (column != null) {
          column.BeginInvoke(new Action(() => {
            column.AutoSearchText = column.Text;
            column.ShowPopup();
          }));
        }
      }
    }

    /// <summary>
    /// 下拉框样式
    /// </summary>
    //[Browsable(true)]
    //public override DevExpress.XtraEditors.Controls.TextEditStyles TextEditStyle {
    //  get { return base.TextEditStyle; }
    //  set { base.TextEditStyle = value; }
    //}

    /// <summary>
    /// 编辑器名称
    /// </summary>
    public override string EditorTypeName => MyGridLookUpEditName;

    /// <summary>
    /// 注册编辑器
    /// </summary>
    public static void RegisterCustomGridLookUpEdit() {
      EditorRegistrationInfo.Default.Editors.Add(
          new EditorClassInfo(
              MyGridLookUpEditName,
              typeof(MyGridLookUpEdit),
              typeof(RepositoryItemMyGridLookUpEdit),
              typeof(GridLookUpEditBaseViewInfo),
              new ButtonEditPainter(),
              true));
    }

    /// <summary>
    /// 创建自定义GridView
    /// </summary>
    /// <returns></returns>
    protected override ColumnView CreateViewInstance() {
      return new MyGridView();
    }

    /// <summary>
    /// 创建自定义GridControl
    /// </summary>
    /// <returns></returns>
    protected override GridControl CreateGrid() {
      return new MyGridControl();
    }
  }


  public class MyGridLookUpPopupForm : PopupGridLookUpEditForm // NEW
  {
    public MyGridLookUpPopupForm(GridLookUpEdit ownerEdit)
        : base(ownerEdit) {
    }

    protected override void OnKeyDown(KeyEventArgs e) {
      if (e.KeyCode == Keys.Tab) {
        this.OwnerEdit.EditValue = QueryResultValue();
        this.OwnerEdit.SendKey(e);
      }
      //else if (e.KeyCode == Keys.Enter) {
      //  /*
      //   * 正常情况下，在输入第一个字符（主要是数字及字母）后，虽然自动弹出了下拉框并过滤了数据，
      //   * 但是此时光标并未定位到下拉框中，导致回车后并未返回匹配到的首行记录
      //   * 此处就是为了解决以上问题，手动定位到首行记录
      //   * add by geping@2018-10-04
      //   */
      //  if (this.Properties.PopupView.RowCount > 0 && this.Properties.PopupView.FocusedRowHandle < 0) {
      //    this.Properties.PopupView.FocusedRowHandle = 0;
      //    this.OwnerEdit.EditValue = QueryResultValue();
      //    this.OwnerEdit.SendKey(e);
      //  }
      //}
      base.OnKeyDown(e);
    }
  }

}
